package org.tigr.htc.server;

/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.xmlrpc.XmlRpc;
import org.apache.xmlrpc.XmlRpcServer;
import org.tigr.htc.common.HTCConfig;
import org.tigr.htc.common.Ulimit;
import org.tigr.htc.server.mw.Server;

/**
 * The <b>CommandServlet</b> class extends the HttpServlet class and acts as the
 * XML-RPC proxy.
 * <p>
 * The actual command execution is delegated to the <code>CommandServer</code> class
 */

public class CommandServlet extends HttpServlet {

	private static final long serialVersionUID = 6449353904844527876L;
	private XmlRpcServer xmlrpc;

    /**
     * During the initialization process of the servlet add the XML-RPC handler and setup the
     * maximum number of threads that are used to handle RPC requests.
     * 
     * @param config
     * @throws ServletException
     */
    public void init(ServletConfig config) throws ServletException {
    	boolean fileHandlesValid = hasMinimumFilehandles();
    	if (! fileHandlesValid) {
    		System.out.println("Warning! Check the hard ulimit setting for open filehandles!");
    	}
    	
    	try {
    	    int maxThreads = Integer.parseInt(HTCConfig.getProperty("xml.rpc.max.threads"));
    		System.out.println("Setting max threads in XMLRPC to " + maxThreads);
    		XmlRpc.setMaxThreads(maxThreads);
    		xmlrpc = new XmlRpcServer();
    		xmlrpc.addHandler("HTCServer", CommandServer.getInstance());
    		xmlrpc.addHandler("MWServer", Server.getInstance());
    	}
    	catch (Exception x) {
    		throw new ServletException("Servlet initialization error: " + x.toString ());
    	}
    }
    
    private boolean hasMinimumFilehandles() {
    	boolean valid = false;
    	try {
			int maxFileHandles = Ulimit.getMaxOpenFileHandles();
			int minimumFileHandles =  Integer.parseInt(HTCConfig.getProperty("minimum.filehandles"));
			if (maxFileHandles >= minimumFileHandles) {
				valid = true;
			}
		} catch (Exception e) {
			// Ignored. A problem determining the ulimit should not cause the service to fail.
		}
		return valid;
    }

    /**
     * This method handles post requests to the HTTP server. It delegates the actual 
     * execution to the XML RPC server class, which in turn delegates it to the
     * CommandServer class.
     *  
     * @param req
     * @param res
     * @throws ServletException
     * @throws IOException
     */
    public void doPost(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        byte[] result = xmlrpc.execute(req.getInputStream ());
        res.setContentType("text/xml");
        res.setContentLength(result.length);
        OutputStream output = res.getOutputStream();
        output.write(result);
        output.flush();
    }


    /**
     * This method handles the get requests to the HTTP server. It delegates the actual 
     * execution to the XML RPC server class, which in turn delegates it to the
     * CommandServer class.
     * 
     * @param req
     * @param res
     * @throws ServletException
     * @throws IOException
     */
    public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        byte[] result = xmlrpc.execute(req.getInputStream ());
        res.setContentType("text/xml");
        res.setContentLength(result.length);
        OutputStream output = res.getOutputStream();
        output.write(result);
        output.flush();
    }

}
